﻿using System;
using System.Collections;

using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.InteropServices;
using System.IO;
using System.IO.Ports;
using System.Drawing;
using System.Text;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading;
using Microsoft.Win32;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using RemoteScriptingLibrary;
using RemoteScriptingLibrary.Microsoft;
using Timer = System.Windows.Forms.Timer;
using Win32 = RemoteScriptingLibrary.Microsoft.Win32.Win32;

using LowLevelGraphics;
using LowLevelGraphics.Filter;

namespace RemoteScriptingLibrary.ScriptCommands
{
    public class Script
    {
        public class OutputEventArgs
        {
            private object m_oData = null;

            public OutputEventArgs(object _oData)
            {
                m_oData = _oData;
            }

            public object Data
            {
                get { return m_oData; }
                set { m_oData = value; }
            }

            public override string ToString()
            {
                return m_oData.ToString();
            }
        }

        public static WebBrowser m_Browser = new WebBrowser();

        public static SerialPort serialPort1 = new SerialPort("COM2", 115200, Parity.None, 8, StopBits.One);

        public delegate void OutputEventHandler(object sender, OutputEventArgs e);
        public static event OutputEventHandler m_OutputEventHandler;    

        static Script()
        {
            m_OutputEventHandler += new OutputEventHandler(Script_m_OutputEventHandler);
            m_Browser.Navigated += new WebBrowserNavigatedEventHandler(m_Browser_Navigated);
            m_Browser.Navigating += new WebBrowserNavigatingEventHandler(m_Browser_Navigating);
        }

        static void Script_m_OutputEventHandler(object sender, Script.OutputEventArgs e)
        {
            
        }

        public static void m_Browser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            //throw new NotImplementedException();
        }

        public static void m_Browser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        public static void OutputEvent(OutputEventArgs e)
        {
            if (m_OutputEventHandler != null)
            {
                m_OutputEventHandler(typeof(Script), e);
            }
        }

        public static void FindClipboardText(string sRegularExpression)
        {
            IntPtr ptr = Win32.GetOpenClipboardWindow();
            string sT = Helper.GetWindowText(ptr);

            string sText = Clipboard.GetText();
            Match match = Regex.Match(sText, sRegularExpression);
            System.Windows.Forms.MessageBox.Show(match.ToString());
        }

        public static void ExistsRegistryKey(string _sPart)
        {
            RegistryHelper.SearchSubKeys(RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Default), _sPart);
            RegistryHelper.SearchSubKeys(RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default), _sPart);
        }

        public static void MessageBox(string _sText)
        {
            System.Windows.Forms.MessageBox.Show(_sText);
        }

        private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
        private static  UInt32 SWP_NOSIZE = 0x0001;
        private static UInt32 SWP_NOMOVE = 0x0002;
        private static UInt32 SWP_SHOWWINDOW = 0x0040;
        
        public static void TopMost(string _sCaption)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sCaption);            
            Win32.SetWindowPos(ptr, HWND_TOPMOST, 0, 0, 0, 0, Win32.SetWindowPosFlags.SWP_NOMOVE | Win32.SetWindowPosFlags.SWP_NOSIZE | Win32.SetWindowPosFlags.SWP_SHOWWINDOW);
        }

        public static void MessageBox(string _sCaption, string _sText)
        {
            System.Windows.Forms.MessageBox.Show(_sText, _sCaption);
        }

        public static void Hallo()
        {
            System.Windows.Forms.MessageBox.Show("Hallo");
        }

        public static void WaitForActiveWindow(string _sTitle)
        {
            System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
            timer.Interval = 500;
            timer.Start();
            timer.Tick += delegate(object sender, EventArgs e)
            {
                IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
                if (ptr != IntPtr.Zero)
                {
                    //System.Windows.Forms.MessageBox.Show("Ok");
                    timer.Stop();
                }
            };
        }

        public static void WaitForActiveWindow(string _sClassName, string _sTitle)
        {
        }

        public static void WaitForActiveWindow(string _sClassName, string _sTitle, int _nTimeOut)
        {
        }

        public static void Beep(uint dwFreq, uint dwDuration)
        {
            Win32.Beep(dwFreq, dwDuration);
        }

        public static void HalloDieter()
        {
            System.Windows.Forms.MessageBox.Show("Hallo Dieter");
        }

        #region Networking Operations
        /// <summary>
        /// Download from internet
        /// </summary>
        public static void Download()
        {
        }

        public static void SendSocket(string _sServer, int _nPort, string _sText)
        {
            RemoteScriptingLibrary.GetSocket.ConnectSocket(_sServer, _nPort);
            string sText = RemoteScriptingLibrary.GetSocket.SocketSendReceive(_sText, _sServer, _nPort);
            System.Windows.Forms.MessageBox.Show(sText);
        }

        public static void Ping()
        {
        }

        public static void Mail(string _sServer, string _sFrom, string _sTo, string _sSubject, string _sBody)
        {
            Mail(_sServer, _sFrom, _sTo, _sSubject, _sBody, null);
        }

        public static void Mail(string _sServer, string _sFrom, string _sTo, string _sSubject, string _sBody, string _sFile)
        {
            // Specify the file to be attached and sent.
            // This example assumes that a file named Data.xls exists in the
            // current working directory.
            // Create a message and set up the recipients.
            MailMessage message = new MailMessage(
               _sFrom,
               _sTo,
               _sSubject,
               _sBody);
            
            if (string.IsNullOrEmpty(_sFile)) return;

            // Create  the file attachment for this e-mail message.
            Attachment data = new Attachment(_sFile, MediaTypeNames.Application.Octet);
            // Add time stamp information for the file.
            ContentDisposition disposition = data.ContentDisposition;
            disposition.CreationDate = System.IO.File.GetCreationTime(_sFile);
            disposition.ModificationDate = System.IO.File.GetLastWriteTime(_sFile);
            disposition.ReadDate = System.IO.File.GetLastAccessTime(_sFile);
            // Add the file attachment to this e-mail message.
            message.Attachments.Add(data);
            //Send the message.
            SmtpClient client = new SmtpClient(_sServer);
            // Add credentials if the SMTP server requires them.
            client.Credentials = CredentialCache.DefaultNetworkCredentials;
            client.Send(message);
            // Display the values in the ContentDisposition for the attachment.
            ContentDisposition cd = data.ContentDisposition;
            Console.WriteLine("Content disposition");
            Console.WriteLine(cd.ToString());
            Console.WriteLine("File {0}", cd.FileName);
            Console.WriteLine("Size {0}", cd.Size);
            Console.WriteLine("Creation {0}", cd.CreationDate);
            Console.WriteLine("Modification {0}", cd.ModificationDate);
            Console.WriteLine("Read {0}", cd.ReadDate);
            Console.WriteLine("Inline {0}", cd.Inline);
            Console.WriteLine("Parameters: {0}", cd.Parameters.Count);
            foreach (DictionaryEntry d in cd.Parameters)
            {
                Console.WriteLine("{0} = {1}", d.Key, d.Value);
            }
            data.Dispose();
        }

        public static void SMS()
        {
        }
        #endregion Networking Operations

        #region File Operations
        public static void DeleteDirectory(string _sPath, bool _bRecursive)
        {
            Directory.Delete(_sPath, _bRecursive);
        }

        public static void CopyFile(string _sSource, string _sDestination)
        {
            File.Copy(_sSource, _sDestination);
        }

        public static void DeleteDirectory(string _sPath)
        {
            Directory.Delete(_sPath);
        }

        public static void MoveDirectory(string _sSource, string _sDest)
        {
            Directory.Move(_sSource, _sDest);
        }

        public static void RenameDirectory(string _sSource, string _sDest)
        {
            Directory.Move(_sSource, _sDest);
        }

        public static void DeleteFile(string _sFile)
        {
            File.Delete(_sFile);
        }

        public static void MakeDir(string _sDir)
        {
            Directory.CreateDirectory(_sDir);
        }

        public static void MoveFile(string _sSource, string _sDestination)
        {
            File.Move(_sSource, _sDestination);
        }
        #endregion File Operations

        #region window operations

        public static string GetControlText(int _ptr)
        {
            return GetControlText(new IntPtr(_ptr));
        }

        public static string GetControlText(IntPtr _ptr)
        {
            StringBuilder sbClassName = new StringBuilder(255);
            Win32.GetClassName(_ptr, sbClassName, 255);
            string sClassName = sbClassName.ToString();

            return Helper.GetStringByClassName(_ptr, sClassName);
        }

        public static void Enable(string _sPartialName, bool _bEnable)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sPartialName);
            Win32.EnableWindow(ptr, _bEnable);
        }

        public static void WriteText(string _sText)
        {
            RemoteControl.TextToKeyPressArray(_sText, false);
        }

        public static void Sauerei()
        {
            System.Windows.Forms.MessageBox.Show("Sauerei");
        }

        public static void WriteText(params Keys[] _keys)
        {
            foreach (Keys key in _keys)
            {
                Win32.PressKey(key);
            }
        }

        public static void WriteEnter()
        {
            Win32.PressKey(Keys.Enter);
        }

        public static void WriteReturn()
        {
            Win32.PressKey(Keys.Return);
        }

        public static void WriteTextToWindow(string _sTitle, string _sText)
        {
            RemoteControl.SynthesizeKeystrokesToWindow(_sTitle, _sText);
        }

        public static void WriteTextToWindow(string _sTitle, string _sClassName, string _sText)
        {
            RemoteControl.SynthesizeKeystrokesToWindow(_sTitle, _sClassName, _sText, true);
        }

        public static void WriteTextToWindow(string _sTitle, string _sClassName, params Keys[] _aKey)
        {
            RemoteControl.SynthesizeKeystrokesToWindow(_sTitle, _sClassName, _aKey);
        }

        public static void SendTextToWindow(string _sTitle, string _sText)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Win32.SendMessage(ptr, (uint)Win32.WM.SETTEXT, 0x0, new StringBuilder(_sText));
        }

        public static void SendTextToWindow(string _sTitle, string _sClassName, string _sText)
        {
            IntPtr ptrHyperTerminal = Helper.GetWindowFromPartialCaption(_sTitle);
            List<IntPtr> aEdit = Helper.GetChildWindows(ptrHyperTerminal);

            List<IntPtr> aWindow = Helper.GetWindowByClassName(aEdit, _sClassName);
            if (aWindow.Count > 0)
            {
                SendTextToWindow(aWindow[0], _sText);
            }
        }

        public static void SendTextToWindow(int ptr, string _sText)
        {
            SendTextToWindow(new IntPtr(ptr), _sText);
        }

        public static void SendTextToWindow(IntPtr ptr, string _sText)
        {
            Win32.SendMessage(ptr, (uint)Win32.WM.SETTEXT, 0x0, new StringBuilder(_sText));
        }

        public static void Enable(IntPtr ptr, bool _bEnable)
        {
            Win32.EnableWindow(ptr, _bEnable);
        }

        public static void Enable(int ptr, bool _bEnable)
        {
            Win32.EnableWindow(new IntPtr(ptr), _bEnable);
        }

        public static void ActivateWindow(string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Win32.SetActiveWindow(ptr);
        }

        public static void Focus(string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Win32.SetFocus(ptr);
        }

        public static void MoveWindow(string _sTitle, int x, int y)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Win32.RECT rect = Rectangle.Empty;
            Win32.GetWindowRect(ptr, out rect);
            MoveWindow(_sTitle, x, y, rect.Width, rect.Height);
        }

        public static void MoveWindow(string _sTitle, int x, int y, int nHeight, int nWidth)
        {
            MoveWindow(_sTitle, x, y, nWidth, nHeight, true);
        }

        public static void MoveWindow(string _sTitle, int x, int y, int nHeight, int nWidth, bool _bRepaint)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Win32.MoveWindow(ptr, x, y, nHeight, nWidth, _bRepaint);
        }

        public static void ForegroundWindow(string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Win32.SetForegroundWindow(ptr);
        }

        public static void MinimizeWindow(string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Win32.ShowWindow(ptr, Win32.SW_SHOWMINIMIZED);
        }

        public static void MinimizeWindow(string _sTitle, string _sClass)
        {
            IntPtr ptr = Win32.FindWindow(_sClass, _sTitle);
            Win32.ShowWindow(ptr, Win32.SW_SHOWMINIMIZED);
        }

        public static void MaximizeWindow(string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Win32.ShowWindow(ptr, Win32.SW_SHOWMAXIMIZED);
        }

        public static void MaximizeWindow(IntPtr ptr)
        {
            Win32.ShowWindow(ptr, Win32.SW_SHOWMAXIMIZED);
        }

        public static void MinimizeWindow(IntPtr ptr)
        {
            Win32.ShowWindow(ptr, Win32.SW_SHOWMINIMIZED);
        }

        public static void Execute(string _sExe, string _sArguments)
        {
            Process.Start(_sExe, _sArguments);
        }

        public static void Execute(string _sExe)
        {
            Process.Start(_sExe);
        }

        public static string GetActiveWindowTitle()
        {
            const int nChars = 256;
            IntPtr handle = IntPtr.Zero;
            StringBuilder Buff = new StringBuilder(nChars);
            handle = Win32.GetForegroundWindow();

            if (Win32.GetWindowText(handle.ToInt32(), Buff, nChars) > 0)
            {
                return Buff.ToString();
            }
            return null;
        }

        public static bool Kill(string _sProcessName)
        {
            Process process = ProcessHelper.GetProcessByPartialName(_sProcessName);
            if (process == null) return false;
            return Kill(process);
        }

        public static bool KillAll(string _sProcessName)
        {
            Process process = Process.GetProcesses()[0];
            while (process != null)
            {
                process = ProcessHelper.GetProcessByPartialName(_sProcessName);
                if (process != null) Kill(process);
            }
            return true;

        }

        public static bool Kill(Process Proc)
        {
            return ProcessHelper.Kill(Proc);
        }

        public static void SetWindowTitle(string _sPartialName, string _sTitle)
        {
            SetWindowTitle(_sPartialName, null, _sTitle);
        }

        public static void SetWindowTitle(string _sPartialName, string _sClassName, string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sPartialName);
            Win32.SetWindowText(ptr, _sTitle);
        }

        public static void CloseWindow(string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            RemoteScriptingLibrary.Microsoft.Win32.Win32.CloseWindow(ptr);
        }

        #endregion window operations

        #region multimedia operations
        /// <summary>
        /// D:\Holger\Pickup\Marni Wing Girl\(HF) chritinas.mp3
        /// </summary>
        /// <param name="_lpstrCommand"></param>
        /// <param name="_lpstrReturnString"></param>
        public static void MCISendString(string _lpstrCommand)
        {
            Win32.mciSendString(_lpstrCommand, null, 0, IntPtr.Zero);
        }

        public static void Play(string _sFile)
        {
            string playCommand = "open \"" + _sFile + "\" type mpegvideo alias MediaFile";
            Win32.mciSendString(playCommand, null, 0, IntPtr.Zero);
            playCommand = "play MediaFile";
            Win32.mciSendString(playCommand, null, 0, IntPtr.Zero);
        }

        public static void PlayAudio(string _sFile)
        {
        }

        public static bool CDTray(bool open)
        {
            int ret = 0;
            //do a switch of the value passed
            switch (open)
            {
                case true:  //true = open the cd
                    ret = Win32.mciSendString("set cdaudio door open", null, 0, IntPtr.Zero);
                    return true;

                case false: //false = close the tray
                    ret = Win32.mciSendString("set cdaudio door closed", null, 0, IntPtr.Zero);
                    return true;

                default:
                    ret = Win32.mciSendString("set cdaudio door open", null, 0, IntPtr.Zero);
                    return true;
            }
        }

        public static void DisplayPic(string _sPic)
        {
            if (!File.Exists(_sPic))
            {
                return;
            }
            Form form = new Form();
            PictureBox box = new PictureBox();
            box.Parent = form;
            box.Dock = DockStyle.Fill;
            box.BackColor = System.Drawing.Color.Blue;
            UnsafeBitmap bitmap = UnsafeBitmap.FromFile(_sPic);
            bitmap.Dispose();
            box.BackgroundImage = bitmap.InternalBitmap;
            box.BackgroundImageLayout = ImageLayout.Zoom;
            form.Show();
        }

        #endregion multimedia operations

        #region misc
        public static void Sleep(int _nTime)
        {
            Thread.Sleep(_nTime);
        }

        public static void Wait(int _nTime)
        {

        }

        public static FileDialog OpenFileDialog()
        {
            OpenFileDialog fd = new OpenFileDialog();
            if (fd.ShowDialog() != DialogResult.OK) return fd;
            return fd;
        }

        public static FileDialog SaveFileDialog()
        {
            SaveFileDialog fd = new SaveFileDialog();
            if (fd.ShowDialog() != DialogResult.OK) return fd;
            return fd;
        }
        #endregion misc

        #region Mouse Operations
        public static void MouseMove(int x, int y, int steps)
        {
            MouseMove(x, y, steps, 30);
        }

        /// <summary>
        /// Take screenshot and search for pattern from window...
        /// </summary>
        /// <param name="_sPattern"></param>
        public static void MouseMove(string _sPattern, int nXOffset, int nYOffset)
        {

        }

        public static void MouseMove(int x, int y, int steps, int ms)
        {
            Win32.POINT start = Point.Empty;
            Win32.GetCursorPos(out start);
            PointF iterPoint = new Point(start.X, start.Y);

            // Find the slope of the line segment defined by start and newPosition
            PointF slope = new PointF(x - start.X, y - start.Y);

            // Divide by the number of steps
            slope.X = slope.X / steps;
            slope.Y = slope.Y / steps;

            // Move the mouse to each iterative point.
            for (int i = 0; i < steps; i++)
            {
                iterPoint = new PointF(iterPoint.X + slope.X, iterPoint.Y + slope.Y);
                Win32.SetCursorPos(Point.Round(iterPoint));
                Thread.Sleep(ms);
            }

            // Move the mouse to the final destination.
            Win32.SetCursorPos(x, y);
        }

        public static void MouseMove()
        {
        }

        public static void MouseClick(uint x, uint y)
        {
            RemoteControl.Click(MouseButtons.Left, x, y, RemoteControl.MOUSESTATE.CLICK);
        }

        public static void MouseClick(MouseButtons mouseButtons, uint x, uint y)
        {
            RemoteControl.Click(mouseButtons, x, y, RemoteControl.MOUSESTATE.CLICK);
        }

        public static void MouseClick(IntPtr ptr, MouseButtons _mb)
        {
            RemoteControl.Click(ptr, _mb);
        }

        public static void MouseClick()
        {
            MouseClick(MouseButtons.Left);
        }

        /// <summary>
        /// Use this like: WindowName->ControlName 
        /// "->" separates the levels actually
        /// </summary>
        /// <param name="sControlNamePath"></param>
        public static void MouseClick(string sControlNamePath)
        {
            if (!sControlNamePath.Contains("->"))
            {
                IntPtr ptr = Helper.GetWindowFromPartialCaption(sControlNamePath);

                Win32.RECT rect;
                Win32.GetWindowRect(ptr, out rect);
                int x = rect.Left + rect.Width / 2;
                int y = rect.Height + rect.Height / 2;
                MouseMove(x, y);
                MouseClick(x, y, MouseButtons.Left);
            }
        }

        public static void Rameshan()
        {
            MessageBox("Rameshan");
        }

        public static void MouseClick(MouseButtons _mb)
        {
            RemoteControl.Click(_mb);
        }

        public static void MouseDown()
        {
            MouseDown(MouseButtons.Left);
        }

        public static void MouseUp()
        {
            MouseUp(MouseButtons.Left);
        }

        public static void MouseUp(MouseButtons _buttons)
        {
            Win32.POINT point = Point.Empty;
            Win32.GetCursorPos(out point);
            RemoteControl.Click(_buttons, (uint)point.X, (uint)point.Y, RemoteControl.MOUSESTATE.UP);
        }

        public static void MouseDown(MouseButtons _buttons)
        {
            Win32.POINT point = Point.Empty;
            Win32.GetCursorPos(out point);
            RemoteControl.Click(_buttons, (uint)point.X, (uint)point.Y, RemoteControl.MOUSESTATE.DOWN);
        }

        public static void MouseMoveClick(string _sTemplatePic)
        {
            Bitmap bitmap = Screenshot("test.jpg");
            Point point = FindScreenPosition(bitmap, Image.FromFile(_sTemplatePic));
            if (point != new Point(-1, -1))
            {
                MouseMove(point.X, point.Y, 100, 10);
                MouseClick();
            }
        }

        //TODO: correct
        /// <summary>
        /// 
        /// </summary>
        /// <param name="_sTitle"></param>
        /// <param name="_mb"></param>
        public static void MouseMoveClick(string _sTitle, MouseButtons _mb)
        {
            MouseMoveClick(Helper.GetWindowFromPartialCaption(_sTitle), _mb);
        }

        /// <summary>
        /// 
        /// </summary>
        public static void MouseMoveClick(int x, int y, int steps, int ms, IntPtr _ptr, MouseButtons _mb)
        {
            MouseMove(x, y, steps, ms);
            MouseClick(_ptr, _mb);
        }

        //TODO: correct
        /// <summary>
        /// 
        /// </summary>
        /// <param name="_ptr"></param>
        /// <param name="_mb"></param>
        public static void MouseMoveClick(IntPtr _ptr, MouseButtons _mb)
        {
            Win32.RECT rect = new Win32.RECT();
            Win32.GetWindowRect(_ptr, out rect);
            MouseMove(rect.X, rect.Y);
        }

        public static void MouseClick(string _sTitle, MouseButtons _mb, int _nClicks)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            RemoteControl.MoveCursorOverControl(ptr);
            for (int i = 0; i < _nClicks; i++)
            {
                RemoteControl.Click(ptr, _mb);
            }
        }

        ///// <summary>
        ///// TODO: check
        ///// </summary>
        ///// <param name="_mb"></param>
        //public static void MouseClick(MouseButtons _mb)
        //{
        //    Helper.Click(IntPtr.Zero, _mb);
        //}

        public static void MouseClick(string _sPartialName, MouseButtons _mb)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sPartialName);
            Helper.Click(ptr, _mb);
        }

        public static void MouseClick(int x, int y, MouseButtons _mb)
        {
        }

        public static void MouseMove(int x, int y)
        {
            Win32.SetCursorPos(x, y);
        }

        public static Bitmap Screenshot(string _sFileName)
        {
            Bitmap bitmap = ImageTools.TakeScreenshot("blub", true);
            bitmap.Save(_sFileName);
            return bitmap;
        }

        public static void HalloHorst()
        {
            SerialDevice.Serial("Hello Horst!");
        }

        //public static Bitmap Screenshot(string _sControlCaption)
        //{
        //    IntPtr ptr = Helper.GetWindowFromPartialCaption(_sControlCaption);
        //    RECT rect = new RECT();
        //    Win32.GetWindowRect(ptr, out rect);

        //    Bitmap bitmap = ImageTools.CaptureScreen(rect.Left, rect.Y, rect.Width, rect.Height, new Size());
        //    return bitmap;
        //}

        //public static Bitmap Screenshot(IntPtr ptr)
        //{
        //    Bitmap bitmap = ImageTools.CaptureCtrl(ptr);
        //    return bitmap;
        //}

        public static Bitmap Screenshot(int x, int y, int width, int height)
        {
            Bitmap bitmap = ImageTools.TakeScreenshot("blub", true);
            bitmap = BitmapFunctions.GetPicturePart(bitmap, new Rectangle(x, y, width, height));
            return bitmap;
        }

        //public static void Browse(Uri url)
        //{
        //    m_Browser.Navigate(url);
        //}

        public static void Browse(string _sUrl)
        {
            m_Browser.Navigate(_sUrl);
        }

        public static void BrowserPrint()
        {
            m_Browser.Print();
        }

        public static void BrowserPageSetupDialog()
        {
            m_Browser.ShowPageSetupDialog();
        }

        public static void BrowserPrintDialog()
        {
            m_Browser.ShowPrintDialog();
        }

        public static void BrowserPrintPreviewDialog()
        {
            m_Browser.ShowPrintPreviewDialog();
        }

        public static void BrowserPropertiesDialog()
        {
            m_Browser.ShowPropertiesDialog();
        }

        public static Point FindScreenPosition(string _sPic, string _sTemplate)
        {
            UnsafeBitmap template = UnsafeBitmap.FromFile(_sTemplate);
            UnsafeBitmap bitmap = UnsafeBitmap.FromFile(_sPic);
            return FindScreenPosition(bitmap, template);
        }

        public static Point FindScreenPosition(UnsafeBitmap _sPic, UnsafeBitmap _sTemplate)
        {
            SimpleTemplateMatching simpleTemplateMatching = new SimpleTemplateMatching();
            //simpleTemplateMatching.MatchingMode = SIMPLE_TEMPLATE_MATCHING_MODE.NORMAL;
            simpleTemplateMatching.BitmapTemplate = _sTemplate;
            new GrayScale().Execute(_sTemplate);
            new GrayScale().Execute(_sPic);

            simpleTemplateMatching.Execute(_sPic);
            if (simpleTemplateMatching.SADPositions.Count > 0)
            {
                return new Point(simpleTemplateMatching.SADPositions[0].BestCol, simpleTemplateMatching.SADPositions[0].BestRow);
            }
            else
            {
                return new Point(-1, -1);
            }
        }

        public static void SelectAll()
        {
            Helper.SendCTRLC();
        }

        public static void SelectAll(string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Helper.SendCTRL(ptr, Keys.A);
        }

        public static void PasteFromClipboard()
        {
            Helper.SendCTRL(Keys.V);
        }

        public static void CutToClipboard()
        {
            Helper.SendCTRLX();
        }

        public static void CopyToClipboard()
        {
            Helper.SendCTRLC();
        }

        public static void PasteFromClipboardToWindow(string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Helper.SendCTRL(ptr,Keys.V);
        }

        public static void CopyToClipboardFromWindow(string _sTitle)
        {
            IntPtr ptr = Helper.GetWindowFromPartialCaption(_sTitle);
            Helper.SendCTRLC();
        }

        public static void ClipboardDelete()
        {
            Clipboard.Clear();
        }

        public static void ClipboardCopy()
        {
            //Clipboard.SetData();
        }

        public static void ClipboardPaste()
        {
            //Clipboard.GetData();
        }

        public static void Serial(params string[] _sText)
        {
            SerialDevice.Serial(_sText);
        }

        public static void Serial()
        {
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
            serialPort1.Open();
            serialPort1.Write("lgi\r\n");
            serialPort1.Write("secret\r\n");
            serialPort1.Write("abcxyz007\r\n");
            Sleep(500);
            //serialPort1.Write("mvr 2 1 0\r\n");

            //Sleep(100);
            serialPort1.Write("rob 3\r\n");
            Sleep(300);
            string sText = string.Join("", myReceivedLines);

            Form form = new Form();
            TextBox tb = new TextBox();
            tb.Multiline = true;
            tb.Dock = DockStyle.Fill;
            tb.Parent = form;
            tb.Text = sText;
            form.ShowDialog();
            serialPort1.Close();

            myReceivedLines.Clear();
        }

        private static List<string> myReceivedLines = new List<string>();

        static void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            var bytesToRead = serialPort1.BytesToRead;
            //myReceivedLines.AddRange(Regex.Split(serialPort1.ReadExisting(), Environment.NewLine));
            myReceivedLines.Add(serialPort1.ReadExisting());

            // Buffer wasn't full. We are at the end of the transmission.
            if (bytesToRead < serialPort1.DataBits)
            {
            }
        }

        public static Control controlNeededForEditor = null;

        public static string LoadScriptToEditorFromURL(string _sUrl)
        {
            string sText = BrowserHelper.RetrieveData(_sUrl);
            controlNeededForEditor.Text = sText;
            return sText;
        }
        #endregion Mouse Operations

        #region Memory Operations

        public void ReadByte(IntPtr ptr)
        {
            Marshal.ReadByte(ptr);
        }

        public void ReadByte(IntPtr ptr, int offset)
        {
            Marshal.ReadByte(ptr, offset);
        }

        public Exception GetExceptionForHRResult(int hrResult)
        {
            return Marshal.GetExceptionForHR(hrResult);
        }

        public Exception GetExceptionForHRResult(int hrResult, IntPtr ptr)
        {
            return Marshal.GetExceptionForHR(hrResult, ptr);
        }

        public int GetExceptionCode()
        {
            return Marshal.GetExceptionCode();
        }

        public int GetHRForLastWin32Error()
        {
            return Marshal.GetHRForLastWin32Error();
        }

        public int GetLastWin32Error()
        {
            return Marshal.GetLastWin32Error();
        }

        public short ReadInt16(IntPtr ptr)
        {
            return Marshal.ReadInt16(ptr);
        }

        public short ReadInt16(IntPtr ptr, int offset)
        {
            return Marshal.ReadInt16(ptr, offset);
        }

        public void WriteInt16(IntPtr ptr, char val)
        {
            Marshal.WriteInt16(ptr, val);
        }

        public void WriteInt16(IntPtr ptr, int offset, char val)
        {
            Marshal.WriteInt16(ptr, offset, val);
        }

        public int ReadInt32(IntPtr ptr)
        {
            return Marshal.ReadInt32(ptr);
        }

        public int ReadInt32(IntPtr ptr, int offset)
        {
            return Marshal.ReadInt32(ptr, offset);
        }

        public void WriteInt32(IntPtr ptr, int val)
        {
            Marshal.WriteInt32(ptr, val);
        }

        public void WriteInt32(IntPtr ptr, int offset, int val)
        {
            Marshal.WriteInt32(ptr, offset, val);
        }

        public long ReadInt64(IntPtr ptr)
        {
            return Marshal.ReadInt64(ptr);
        }

        public long ReadInt64(IntPtr ptr, int offset)
        {
            return Marshal.ReadInt64(ptr, offset);        
        }

        public void WriteInt64(IntPtr ptr, long val)
        {
            Marshal.WriteInt64(ptr, val);
        }

        public void WriteInt64(IntPtr ptr, int offset, long val)
        {
            Marshal.WriteInt64(ptr, offset, val);
        }

        public IntPtr ReadIntPtr(IntPtr ptr)
        {
            return Marshal.ReadIntPtr(ptr);
        }

        public void WriteIntPtr(IntPtr ptr, IntPtr val)
        {
            Marshal.WriteIntPtr(ptr, val);
        }

        public void WriteIntPtr(IntPtr ptr, int offset, IntPtr val)
        {
            Marshal.WriteIntPtr(ptr, offset, val);
        }

        public IntPtr ReadIntPtr(IntPtr ptr, int offset)
        {
            return Marshal.ReadIntPtr(ptr, offset);
        }

        public void TrayTip(string _sText, string _sIconPath)
        {
            ToolTipHelper.TrayTip(_sText, _sIconPath);
        }

        #endregion Memory Operations
    }
}
